package com.zhuojy.equity.mall.admin.core;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.zhuojy.equity.mall.admin.common.constant.Constants;
import com.zhuojy.equity.mall.admin.common.constant.JwtConstants;
import com.zhuojy.equity.mall.admin.common.exception.Asserts;
import com.zhuojy.equity.mall.admin.common.exception.BizException;
import com.zhuojy.equity.mall.admin.dal.dataobject.TResourceDO;
import com.zhuojy.equity.mall.admin.dal.dataobject.TUserDO;
import com.zhuojy.equity.mall.admin.manager.ResourceManager;
import com.zhuojy.equity.mall.admin.manager.RoleResourceRelationManager;
import com.zhuojy.equity.mall.admin.manager.UserManager;
import com.zhuojy.equity.mall.admin.manager.UserRoleRelationManager;
import com.zhuojy.equity.mall.admin.manager.bo.AdminUserDetails;
import com.zhuojy.equity.mall.admin.manager.bo.LoginBO;
import com.zhuojy.equity.mall.admin.manager.cache.RedisManager;
import com.zhuojy.equity.mall.admin.manager.token.TokenManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import com.zhuojy.equity.mall.admin.common.utils.StringUtils;
import java.util.List;

/**
 * 用户登录核心业务逻辑处理类
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class LoginCore {

	private final TokenManager tokenManager;

	private final UserManager userManager;

	private final ResourceManager resourceManager;

	private final PasswordEncoder passwordEncoder;

	private final UserRoleRelationManager userRoleRelationManager;

	private final RoleResourceRelationManager roleResourceRelationManager;

	private final RedisManager redisCache;

	public AdminUserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// 查询用户
		TUserDO tUserDO = userManager.queryUserByUsername(username);
		if (ObjUtil.isNull(tUserDO)) {
			Asserts.UsernameNotFoundException();
		}
		// 查询角色id列表
		List<Long> roleIdList = userRoleRelationManager.queryRoleIdListByUserId(tUserDO.getId());
		// 查询资源id列表
		List<Long> resourceIdList = roleResourceRelationManager.queryResourceIdListByRoleIds(roleIdList);
		// 查询资源对象列表
		List<TResourceDO> resourceDOList = resourceManager.queryByIdList(resourceIdList);
		return new AdminUserDetails(tUserDO, resourceDOList);
	}

	public void usernamePasswordAuthentication(LoginBO loginBO) throws BizException {
		AdminUserDetails adminUserDetails = loginBO.getAdminUserDetails();
		System.out.println(loginBO.getPassword());
		System.out.println(adminUserDetails.getPassword());
		if (!passwordEncoder.matches(loginBO.getPassword(), adminUserDetails.getPassword())) {
			Asserts.fail("密码不正确");
		}
		if (!adminUserDetails.isEnabled()) {
			Asserts.fail("帐号已被禁用");
		}
		UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(adminUserDetails, null,
				adminUserDetails.getAuthorities());
		SecurityContextHolder.getContext().setAuthentication(authentication);
		String token = tokenManager.generateToken(adminUserDetails);
		if (StrUtil.isBlank(token)) {
			Asserts.fail("用户名或密码错误");
		}
		loginBO.setToken(token);
		loginBO.setTokenHead(JwtConstants.TOKEN_HEAD);
	}

	public void validateCaptcha(LoginBO loginBO) throws BizException{
		String verifyKey = Constants.CAPTCHA_CODE_KEY + StringUtils.nvl(loginBO.getUuid(), "");

		String captcha = redisCache.queryNoSerializableRedisValue(verifyKey);
		redisCache.deleteObject(verifyKey);
		if (captcha == null)
		{
			Asserts.fail("验证码过期");
		}
		if (!loginBO.getCode().equalsIgnoreCase(captcha))
		{
			Asserts.fail("验证码错误");
		}
	}
}
